package rsj.api.contract.entity;

import com.alibaba.fastjson.annotation.JSONField;
import common.statusenum.ChargeEnum;
import common.statusenum.ServiceStatusEnum;
import lombok.Data;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 合同详情
 *
 * @author yuanqinglong
 * @since 2021/8/4 17:52
 */
@Data
public class ContractDetail {

    /**
     * 合同id
     */
    private String orgpId;
    /**
     * 接口编号（，拼接）
     */
    private String orgpProdUid;
    /**
     * 接口名称
     */
    private String orgpProdName;
    /**
     * 合同状态（0停用、1启用）
     */
    private String orgpOrgpstatus;
    /**
     * 生效日期
     */
    @JSONField(format = "yyyy-MM-dd")
    private LocalDate orgpCtime;
    /**
     * 到期日期
     */
    @JSONField(format = "yyyy-MM-dd")
    private LocalDate orgpEndtime;
    /**
     * 财务方式：1单条，2包量，3包企业数
     */
    private String orgpBillmethod;
    /**
     * 接口计费方式（prodUid#1）
     */
    private String orgpProdCharge;
    /**
     * 已用量
     */
    private String orgpUseamount;
    /**
     * 剩余量
     */
    private Integer orgpRemaining;
    /**
     * 剩余天数
     */
    private String remainingDays;
    /**
     * 上游使用量
     */
    private String statUpUseamount;

    /**
     * 业务合同编号
     */
    private String orgpBusId;
    /**
     * 操作人
     */
    private String orgpOperson;
    /**
     * 购买量
     */
    private Integer orgpBuyamount;
    /**
     * 合同时间
     */
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime orgpContractime;
    /**
     * 使用状态( 30、50、60...)
     */
    private String orgpStatus;
    /**
     * 操作状态（已到期不可点击操作）
     */
    private Boolean operatingStatus = false;


    /**
     * 翻译合同状态
     */
    public void translationContractStatus() {
        orgpStatus = ServiceStatusEnum.getMsgByCode(orgpStatus);
    }

    /**
     * 计算产品使用
     */
    public void calculateProductUsage(Map<String, ContractStatistic> productUsage) {
        // 此合同下的产品
        // 保存合同中每个接口的使用量
        List<Integer> usageNum = new ArrayList<>();
        // 保存合同中每个接口的计费方式
        List<String> charges = new ArrayList<>();
        // 保存合同中每个接口的上游使用量
        List<Integer> upUseAmount = new ArrayList<>();
        if (!Objects.isNull(orgpProdCharge)) {
            String[] prods = orgpProdCharge.split(",");
            for (String prod : prods) {
                // （prodUid#1）截取#  获取 产品计费方式
                String[] prodUidCharge = prod.split("#");
                charges.add(ChargeEnum.getMsgByCode(prodUidCharge[1]));
                // 如果这个合同没有统计记录 或者 这个 接口没有统计记录 使用量为0
                if (CollectionUtils.isEmpty(productUsage) || !productUsage.containsKey(prodUidCharge[0])) {
                    usageNum.add(0);
                    upUseAmount.add(0);
                    continue;
                }
                // 获取合同中这个接口的统计数据
                ContractStatistic contractStatistics = productUsage.get(prodUidCharge[0]);
                // 此接口上游使用量
                upUseAmount.add(contractStatistics.getStatUpUseamount());
                switch (prodUidCharge[1]) {
                    // 查询计费
                    case ChargeEnum.QUERY_CODE:
                        usageNum.add(contractStatistics.getStatFindoutNum() + contractStatistics.getStatNullNum());
                        break;
                    // 查得计费
                    case ChargeEnum.FIND_OUT_CODE:
                        usageNum.add(contractStatistics.getStatFindoutNum());
                        break;
                    // 包企业数计费 只展示合同中的使用量
                    case ChargeEnum.ENTERPRISE_BILLING_CODE:
                        usageNum.add(Integer.parseInt(orgpUseamount));
                        break;
                    default:
                        usageNum.add(0);
                }
            }
            this.processingDaysRemaining();
            this.formatProductName(charges);
        } else {
            String[] split = orgpProdUid.split(",");
            for (int i = 0; i < split.length; i++) {
                usageNum.add(0);
                upUseAmount.add(0);
            }
            remainingDays = "-";
        }
        // 计算产品使用量
        orgpUseamount = usageNum.stream().map(integer -> Objects.equals(integer, 0) ? "-" : String.valueOf(integer)).collect(Collectors.joining(","));
        // 上游使用量
        statUpUseamount = upUseAmount.stream().map(integer -> Objects.equals(integer, 0) ? "-" : String.valueOf(integer)).collect(Collectors.joining(","));
        // 计算剩余量
        orgpRemaining = orgpBuyamount - usageNum.stream().mapToInt(value -> value).sum();
        this.translationContractStatus();
    }


    /**
     * 处理剩余几天
     */
    private void processingDaysRemaining() {
        // 服务到期 或 试用到期 剩余天数展示  已到期
        if (Objects.equals(ServiceStatusEnum.TRIAL_EXPIRES_CODE, orgpStatus)
                || Objects.equals(ServiceStatusEnum.SERVICE_EXPIRATION_CODE, orgpStatus)) {
            remainingDays = "已到期";
            return;
        }
        // 计算剩余天数
        remainingDays = String.valueOf(orgpEndtime.toEpochDay() - LocalDate.now().toEpochDay());
        operatingStatus = true;
    }


    /**
     * 格式的产品名称
     *
     * @param charges 指控
     */
    private void formatProductName(List<String> charges) {
        String[] prodNames = orgpProdName.split(",");
        for (int i = 0; i < prodNames.length; i++) {
            prodNames[i] += "(" + charges.get(i) + ")";
        }
        orgpProdName = String.join(",", prodNames);
    }

}
